package com.cn.dlr.zk.案列0;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * @author: dlr
 * @data: 2019/8/7 21:53
 * @desc: zk测试
 */
public class TestZk {
    private Logger logger= LoggerFactory.getLogger(TestZk.class);
    //连接地址
    private static final String connectString = "192.168.10.20:2181,192.168.10.30:2181,192.168.10.40:2181";
    //session 会话
    private static final int sessionTimeout = 2000;
    ZooKeeper zooKeeper;
    /*
     * @author: dlr
     * @desc:   连接zk服务端
     * @date: 2019/8/7
     * @param
     * @return: void
     */
    @Before
    public void init() throws  Exception{
        //得到zk服务端对象
        zooKeeper= new ZooKeeper(connectString, sessionTimeout, new Watcher(){
            @Override
            public void process(WatchedEvent event) {
                try{
                    int i=0;
                    List<String> childNodes=zooKeeper.getChildren("/",true);
                    for (String child:childNodes){
                        ++i;
                        logger.info("第"+i+"个节点:"+child);
                    }
                }
                catch (Exception e){
                    e.printStackTrace();
                }
            }
        });
    }
    /*
     * @author: dlr
     * @desc:创建持久无序节点
     * @date: 2019/8/7
     * @param  Ids: ANYONE_ID_UNSAFE:谁都可以读 READ_ACL_UNSAFE:只读 OPEN_ACL_UNSAFE:开放的 CREATOR_ALL_ACL:应答模式
                    PERSISTENT 持久化节点 PERSISTENT_SEQUENTIAL 顺序自动编号持久化节点
                    EPHEMERAL  临时节点   EPHEMERAL_SEQUENTIAL  临时自动编号节点
     * @return: void
     */
    @Test
    public void createNode() throws  Exception{
        String path = zooKeeper.create("/first/second", "node-a-a".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        logger.info("创建成功",path);

    }
    /*
     * @author: dlr
     * @desc:  监听节点下的子节点不包括孙子,这样不能动态监听,因为程序执行完会断开与服务器的连接
     *         让程序休眠保持一直运行Thread.sleep(Long.MAX_VALUE),但仍不会动态监听,请看监听原理
     *         下边的方法只是告知服务器,将节点添加到zk服务的监听列表,节点的便会是zk服务端感知的,并
     *         通知客户端的,所以要在连接服务端的代码中获取节点的变化
     *
     * @date: 2019/8/7
     * @param
     * @return: void
     */
    @Test
    public void watchNodeChange() throws  Exception{
        //告知服务器,监听此节点,并返回该节点下的所有子节点(并不会返回孙子节点)
        int i=0;
        List<String> childNodes=zooKeeper.getChildren("/",true);
        for (String child:childNodes){
            ++i;
            logger.info("第"+i+"个节点:"+child);
        }
        Thread.sleep(Long.MAX_VALUE);
    }
    /*
     * @author: dlr
     * @desc:    判断系统是否存在
     * @date: 2019/8/7
     * @param
     * @return: void
     */
    @Test
    public void exitNode() throws  Exception{
        Stat stat=zooKeeper.exists("/first",false);
        logger.info(stat.toString());
    }
}
